package kz.pompei.ifacer.model.widgets;

import java.io.PrintStream;
import java.util.UUID;

public abstract class Widget {
  public UUID uuid;
  public int x = 10, y = 10;
  public boolean active = true;
  
  public Widget() {
    resetUuid();
  }
  
  public Widget(UUID uuid) {
    this.uuid = uuid;
  }
  
  public final Widget resetUuid() {
    uuid = UUID.randomUUID();
    return this;
  }
  
  public void assignTo(Widget widget) {
    widget.x = x;
    widget.y = y;
  }
  
  public void takePosition(Widget widget) {
    x = widget.x;
    y = widget.y;
  }
  
  public void move(int dx, int dy) {
    x += dx;
    y += dy;
  }
  
  public abstract Widget copy();
  
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((uuid == null) ? 0 :uuid.hashCode());
    return result;
  }
  
  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null) return false;
    if (getClass() != obj.getClass()) return false;
    Widget other = (Widget)obj;
    if (uuid == null) {
      if (other.uuid != null) return false;
    } else if (!uuid.equals(other.uuid)) return false;
    return true;
  }
  
  protected static void checkWidget(Widget widget, Class<?> clas) {
    if (widget == null) {
      throw new IllegalArgumentException("widget == null");
    }
    if (!(clas.isAssignableFrom(widget.getClass()))) {
      throw new IllegalArgumentException("widget must has class " + clas + ", but it has class "
          + widget.getClass());
    }
  }
  
  protected static String space(int offset) {
    StringBuilder s = new StringBuilder(offset * 2);
    for (int i = 0; i < offset; i++) {
      s.append("  ");
    }
    return s.toString();
  }
  
  public void print(int offset, PrintStream out) {
    String s = space(offset);
    out.println(s + "<widget type=\"" + getClass().getSimpleName() + "\" uuid=\"" + uuid + "\">");
    out.println(s + "  <x v=\"" + x + "\"/>");
    out.println(s + "  <y v=\"" + y + "\"/>");
    out.println(s + "  <active v=\"" + active + "\"/>");
    printFields(offset + 1, out);
    out.println(s + "</widget>");
  }
  
  protected abstract void printFields(int offset, PrintStream out);
}
